/*******************************************************************************
 * @author scl
 * @email shchlu188@163.com
 ******************************************************************************/

#include "bsp_serial.h"

/*串口句柄存放数组*/
static UART_HandleTypeDef com_tb[COM_SIZE];

/********************************串口 通用**********************************************/
/**
 * @brief 获取串口句柄
 * @param port 
 * @return 
 */
inline UART_HandleTypeDef *com_handle_get(serial_port_type port) {
    return &com_tb[port];
}

/********************************串口1 START**********************************************/
void com1_init(uint32_t baud) {
    UART_HandleTypeDef *ptr = com_handle_get(com1);

    ptr->Instance = USART1;
    ptr->Init.BaudRate = baud;
    ptr->Init.WordLength = UART_WORDLENGTH_8B;
    ptr->Init.StopBits = UART_STOPBITS_1;
    ptr->Init.Parity = UART_PARITY_NONE;
    ptr->Init.Mode = UART_MODE_TX_RX;
    ptr->Init.HwFlowCtl = UART_HWCONTROL_NONE;
    ptr->Init.OverSampling = UART_OVERSAMPLING_16;
    HAL_UART_DeInit(ptr);
    if (HAL_UART_Init(ptr) != HAL_OK) {
        error_handle();
    }
}
/********************************串口1 END**********************************************/
/********************************串口3 START**********************************************/

void com3_init(uint32_t baud) {

    UART_HandleTypeDef *ptr = com_handle_get(com3);
    ptr->Instance = USART3;
    ptr->Init.BaudRate = baud;
    ptr->Init.WordLength = UART_WORDLENGTH_8B;
    ptr->Init.StopBits = UART_STOPBITS_1;
    ptr->Init.Parity = UART_PARITY_NONE;
    ptr->Init.Mode = UART_MODE_TX_RX;
    ptr->Init.HwFlowCtl = UART_HWCONTROL_NONE;
    ptr->Init.OverSampling = UART_OVERSAMPLING_16;
    HAL_UART_DeInit(ptr);
    if (HAL_UART_Init(ptr) != HAL_OK) {
        error_handle();
    }
}
/********************************串口3 END**********************************************/

/********************************HAL 库串口硬件通用**********************************************/
static inline void com_gpio_init(GPIO_TypeDef *tx_port, uint32_t tx_pin, GPIO_TypeDef *rx_port, uint32_t rx_pin) {
    GPIO_InitTypeDef GPIO_InitStruct = {.Pin=tx_pin, .Mode=GPIO_MODE_AF_PP, .Speed=GPIO_SPEED_FREQ_HIGH};
    HAL_GPIO_Init(tx_port, &GPIO_InitStruct);
    GPIO_InitStruct.Pin = rx_pin;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(rx_port, &GPIO_InitStruct);
}

/********************************HAL 库串口硬件驱动初始化**********************************************/
void HAL_UART_MspInit(UART_HandleTypeDef *uartHandle) {

    if (uartHandle->Instance == USART1) {
        /* USART1 clock enable */
        __HAL_RCC_USART1_CLK_ENABLE();
        __HAL_RCC_GPIOA_CLK_ENABLE();
        /**USART1 GPIO Configuration
        PA9     ------> USART1_TX
        PA10     ------> USART1_RX
        */
        com_gpio_init(GPIOA, GPIO_PIN_9, GPIOA, GPIO_PIN_10);
#if COM1_IT_ENABLE
        /* USART1 interrupt Init */
    HAL_NVIC_SetPriority(USART1_IRQn, COM1_IT_PreemptPriority, COM1_IT_SubPriority);
    HAL_NVIC_EnableIRQ(USART1_IRQn);
#endif
    } else if (uartHandle->Instance == USART3) {
        __HAL_RCC_USART3_CLK_ENABLE();
        __HAL_RCC_GPIOB_CLK_ENABLE();
        /**USART3 GPIO Configuration
            PB10     ------> USART3_TX
            PB11     ------> USART3_RX
        */
        com_gpio_init(GPIOB, GPIO_PIN_10, GPIOB, GPIO_PIN_11);
#if COM3_IT_ENABLE
        /* USART3 interrupt Init */
        HAL_NVIC_SetPriority(USART3_IRQn, COM3_IT_PreemptPriority, COM3_IT_SubPriority);
        HAL_NVIC_EnableIRQ(USART3_IRQn);
#endif
    }
}

void HAL_UART_MspDeInit(UART_HandleTypeDef *uartHandle) {

    if (uartHandle->Instance == USART1) {
        /* Peripheral clock disable */
        __HAL_RCC_USART1_CLK_DISABLE();
        HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9 | GPIO_PIN_10);
#if COM1_IT_ENABLE
        /* USART1 interrupt Deinit */
    HAL_NVIC_DisableIRQ(USART1_IRQn);
#endif
    } else if (uartHandle->Instance == USART3) {
        __HAL_RCC_USART3_CLK_DISABLE();
        HAL_GPIO_DeInit(GPIOB, GPIO_PIN_10 | GPIO_PIN_11);
#if COM3_IT_ENABLE
        /*  interrupt Deinit */
        HAL_NVIC_DisableIRQ(USART3_IRQn);
#endif
    }
}